import os
import time
import requests
import json
from datetime import datetime
from bs4 import BeautifulSoup
from urllib import parse


# 英雄列表 json
hero_url = 'https://pvp.qq.com/web201605/js/herolist.json'
# 目标地址
base_url = 'https://apps.game.qq.com/cgi-bin/ams/module/ishow/V1.0/query/workList_inc.cgi'
# 请求头
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36',
}
# 图片请求头
img_headers = {
    'Host': 'shp.qpic.cn',
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.106 Safari/537.36',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9',
    'Accept-Encoding': 'gzip, deflate',
    'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7',
    'If-Modified-Since': 'Thu, 17 Jun 2021 09:37:55 GMT',
}
# 基本请求参数
base_params = {
    'activityId': 2735,
    'sVerifyCode': 'ABCD',
    'sDataType': 'JSON',
    # 条数
    'iListNum': 20,
    'totalpage': 0,
    # 页码 初始是 0
    'page': 0,
    'iOrder': 0,
    'iSortNumClose': 1,
    # jsonp 回调函数名
    'jsoncallback': 'jQuery17107549164308048077_1624074181751',
    'iAMSActivityId': 51991,
    '_everyRead': 'true',
    'iTypeId': 2,
    'iFlowId': 267733,
    'iActId': 2735,
    'iModuleId': 2735,
    '_': 1623401191802,
}

# 当前目录
root_path = os.getcwd()
# 图片存放文件夹 image | img
base_img_path = 'img'

# 总页数
total_page = 0
# 页码，从 0 开始
current_page = -1
# 最后的结果列表
result_list = []
# 英雄 列表
hero_list = []


# 处理 请求参数，拼接
def handle_params(params_obj):
    query_str = '?'
    for k in params_obj:
        query_str += (k + '=' + str(params_obj[k]) + '&')
    # 修正一下参数 &
    if query_str.endswith('&'):
        query_str = query_str[0:-1]
    return query_str


# 获取接口有效的 json 数据
def get_json(url):
    # 结果
    res = requests.get(url, headers)
    # 解析美化
    soup = BeautifulSoup(res.text, 'lxml')
    # BeautifulSoup 返回的是包装对象，每一个标签都是都可以通过 tag 来获取，并且支持css选择器
    str_text = soup.p.string
    # 切割出有效json字符串
    start = len(base_params['jsoncallback']) + 1
    str_json = (str_text[start:-2])
    # 转换为 json
    obj_json = json.loads(str_json)
    # 获取总页数
    global total_page
    if total_page == 0:
        total_page = int(obj_json['iTotalPages'])
    # 返回
    return obj_json


# 获取所有英雄列表
def get_hero_json(url):
    res = requests.get(url).json()
    global hero_list
    hero_list = res
    return res


# 将图片路径写入文件保存
def write_txt(obj):
    with open('text.txt', 'a+') as f:
        for x in obj['List']:
            # parse 解码
            img_url = parse.unquote(x['sProdImgNo_8'])
            # 根据 预览图 替换 大图 地址
            big_img_url = img_url.replace(img_url[-3:], '0', 1)
            # 写入文件中储存
            f.write(big_img_url + '\n')
            # 储存到 全局变量中
            result_list.append(big_img_url)


# 保存图片地址 到 全局
def save_img_url(obj):
    for x in obj['List']:
        # parse 解码
        img_url = parse.unquote(x['sProdImgNo_8'])
        # 根据 预览图 替换 大图 地址
        big_img_url = img_url.replace(img_url[-3:], '0', 1)
        # 储存到 全局变量中
        if img_url not in result_list:
            result_list.append(big_img_url)


# 开始 获取 图片地址
def start():
    # 拼接参数
    query = handle_params(base_params)
    # 目标地址
    target_url = base_url + query
    # 获取 json
    res_obj = get_json(target_url)
    # 保存图片地址 到全局
    # save_img_url(res_obj)
    # 将图片路径写入文件储存
    write_txt(res_obj)


# 从 文件中读取地址 根据 地址去下载图片 到文件夹
def download_img():
    print('开始下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    t1 = datetime.now()
    # 读取文件
    with open('text.txt', 'r') as f:
        # 一行行读取，需要去除 \n
        lines = f.readlines()
        for l in lines:
            if l == '\n':
                continue
            if l.endswith('\n'):
                l = l[0:-1]
            # 创建 image 文件夹
            if not os.path.exists('./' + base_img_path):
                os.makedirs('./' + base_img_path)
            # 下载图片
            res_data = requests.get(l, headers=img_headers).content
            # 替换图片中的特殊字符
            img_path = l.replace('/', '-').replace(':', '') + '.jpg'
            # 将图片保存到 当前目录下的 image 文件夹
            with open(root_path + '/' + base_img_path + '/' + img_path, 'wb+') as ff:
                ff.write(res_data)
    t2 = datetime.now()
    print('结束下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    print('耗时： ', (t2 - t1).seconds, ' 秒')


# 从 全局列表 中获取地址下载 到 image 文件夹
def load_img():
    print('开始下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    t1 = datetime.now()
    # 创建 image 文件夹
    if not os.path.exists('./' + base_img_path):
        os.makedirs('./' + base_img_path)
    # 计数器
    count = 0
    for l in result_list:
        # 计数器
        count += 1
        print('正在下载第 ' + str(count) + ' / ' + str(len(result_list)) + '张图片...')
        # 下载图片
        res_data = requests.get(l, headers=img_headers).content
        # 替换图片中的特殊字符 / :
        img_path = l.replace('/', '-').replace(':', '') + '.jpg'
        # 将图片保存到 当前目录下的 image 文件夹
        with open(root_path + '/' + base_img_path + '/' + img_path, 'wb+') as ff:
            ff.write(res_data)
    t2 = datetime.now()
    print('结束下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    print('耗时： ', (t2 - t1).seconds, ' 秒')


# 根据英雄列表 json 数据 下载 皮肤 图片
def load_hero_skin_img():
    # 创建文件夹
    if not os.path.exists('./' + base_img_path):
        os.makedirs('./' + base_img_path)
    try:
        print('开始下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        t1 = datetime.now()
        # 英雄数据
        res_list = get_hero_json(hero_url)
        # 遍历英雄，获取所有皮肤
        for i in range(len(res_list)):
            # 编号
            ename = res_list[i]['ename']
            # 英雄名
            cname = res_list[i]['cname']
            # 皮肤名字 可能不存在皮肤名字
            # skin_name_list = []
            if 'skin_name' in res_list[i]:
                skin_name_list = res_list[i]['skin_name'].split('|')
            else:
                # 马超皮肤 无 skin_name 字段，马超 3 个皮肤
                skin_name_list = ['1', '2', '3']
            print('正在下载第 ' + str(i + 1) + ' / ' + str(len(res_list)) + ' 个英雄： ' + cname + ' 的皮肤...')
            # 下载
            for bigskin in range(1, len(skin_name_list) + 1):
                # 拼接皮肤地址
                pic_url = 'http://game.gtimg.cn/images/yxzj/img201606/skin/hero-info/' + str(ename) + '/' + str(ename) + '-bigskin-' + str(bigskin) + '.jpg'
                # 获取图片
                picture = requests.get(pic_url).content
                # 写入 img
                print(ename, cname, skin_name_list[bigskin - 1])
                with open(root_path + '/' + base_img_path + '/' + cname + '-' + skin_name_list[bigskin - 1] + '.jpg', 'wb+') as f:
                    f.write(picture)
        t2 = datetime.now()
        print('结束下载图片：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        print('耗时： ', (t2 - t1).seconds, ' 秒')
    except Exception:
        print('...error...')
        pass
    else:
        print('...done...')


if __name__ == '__main__':
    # print('开始获取地址时间：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    # d1 = datetime.now()
    # # 遍历，当前页码小于总页码时，遍历获取 地址
    # while current_page < total_page:
    #     current_page += 1
    #     base_params['page'] = current_page
    #     print('正在获取 第 ' + str(current_page) + ' / ' + str(total_page) + ' 页 图片地址...')
    #     # 开始获取图片url
    #     start()
    # d2 = datetime.now()
    # print('结束地址时间：', time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    # print('结果条数为：', len(result_list))
    # print('耗时： ', (d2 - d1).seconds, ' 秒')

    # 开始下载图片
    # load_img()

    # 开始下载图片
    # download_img()

    # 根据英雄 json 下载皮肤图片
    load_hero_skin_img()
